package com.hancher.gamelife5.money;

import android.os.Bundle;

import androidx.annotation.NonNull;

import com.chad.library.adapter.base.BaseQuickAdapter;
import com.chad.library.adapter.base.viewholder.BaseViewHolder;
import com.github.gzuliyujiang.calendarpicker.CalendarPicker;
import com.hancher.api.PgyerApi;
import com.hancher.api.SupabaseManager;
import com.hancher.bean.MoneyDTO;
import com.hancher.common.androidutil.AsyncUtils;
import com.hancher.common.androidutil.IntentUtil;
import com.hancher.common.androidutil.KeyEventUtil;
import com.hancher.common.androidutil.MmkvUtil;
import com.hancher.common.androidutil.ScreenAlwaysLightUtil;
import com.hancher.common.androidutil.ToastUtil;
import com.hancher.common.base.BaseActivity;
import com.hancher.common.base.BaseApplication;
import com.hancher.common.javautil.DateUtil;
import com.hancher.common.javautil.EmptyUtil;
import com.hancher.common.javautil.GsonUtil;
import com.hancher.common.javautil.StringUtil;
import com.hancher.common.net.NetUtil;
import com.hancher.common.net.download.DownloadHelper;
import com.hancher.common.net.download.DownloadListener;
import com.hancher.money.R;
import com.hancher.money.databinding.ActivityMoneyListBinding;
import com.hancher.plugins.hrlog.HrLogUtil;
import com.hancher.plugins.hrpage3.PageRecyclerViewManager;
import com.hjq.permissions.Permission;
import com.hjq.permissions.XXPermissions;
import com.lxj.xpopup.XPopup;
import com.lxj.xpopup.core.BasePopupView;
import com.lxj.xpopup.impl.LoadingPopupView;
import com.lxj.xpopup.interfaces.OnCancelListener;
import com.lxj.xpopup.interfaces.OnConfirmListener;
import com.lxj.xpopup.interfaces.OnInputConfirmListener;
import com.scwang.smart.refresh.layout.api.RefreshLayout;
import com.scwang.smart.refresh.layout.listener.OnRefreshLoadMoreListener;

import java.io.File;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import io.reactivex.rxjava3.disposables.Disposable;
import okhttp3.MediaType;
import okhttp3.RequestBody;

/**
 * 作者 : Hancher ytu_shaoweijie@163.com <br/>
 * 时间 : 2023/3/12 0012 22:49 <br/>
 * 描述 :
 */
public class MoneyListActivity extends BaseActivity<ActivityMoneyListBinding> {

    private PgyerApi.LastestApkBean lastestApkBean;
    private BasePopupView updateDialog = null;
    private PageRecyclerViewManager<MoneyDTO> prvm;
    private Long startStamp;
    private Long endStamp;
    @Override
    protected void onResume() {
        super.onResume();
        if (MmkvUtil.getBoolean("LOGIN", true)) {
            new XPopup.Builder(this)
                    .dismissOnBackPressed(false)
                    .dismissOnTouchOutside(false)
                    .asInputConfirm("登录", "密码为生日,例19990101", "", null,
                            new OnInputConfirmListener() {
                                @Override
                                public void onConfirm(String content) {
                                    if ("19960819".equals(content)) {
                                        MmkvUtil.put("LOGIN", false);
                                        queryList(PageRecyclerViewManager.FRESH);
                                        queryTotal();
                                        checkUpdate();
                                    } else {
                                        MoneyListActivity.this.finish();
                                    }
                                }
                            }, new OnCancelListener() {
                                @Override
                                public void onCancel() {
                                    MoneyListActivity.this.finish();
                                }
                            }, 0)
                    .show();
            return;
        }
        queryList(PageRecyclerViewManager.FRESH);
        queryTotal();
        checkUpdate();

    }

    private void checkUpdate() {
        @io.reactivex.rxjava3.annotations.NonNull
        Disposable d = PgyerApi.getLastest().subscribe(bean -> {
            HrLogUtil.d("检查版本成功");
            PgyerApi.LastestApkBean lastestApk = bean.getData();
            if (lastestApk == null) {
                HrLogUtil.e("未知异常");
                return;
            }
            this.lastestApkBean = lastestApk;
            if (lastestApkBean == null) {
                return;
            }
            if (!lastestApkBean.getBuildHaveNewVersion()) {
                return;
            }
            if (updateDialog == null) {
                updateDialog = new XPopup.Builder(this)
                        .isDestroyOnDismiss(true)
                        .dismissOnBackPressed(false)
                        .dismissOnTouchOutside(false)
                        .asConfirm("提示", "有新版本，是否更新？", "取消", "确定", new OnConfirmListener() {
                            @Override
                            public void onConfirm() {
                                XXPermissions.with(MoneyListActivity.this)
                                        .permission(Permission.REQUEST_INSTALL_PACKAGES)
                                        .permission(Permission.READ_MEDIA_IMAGES)
                                        .permission(Permission.READ_MEDIA_VIDEO)
                                        .permission(Permission.READ_MEDIA_AUDIO)
                                        .permission(Permission.WRITE_EXTERNAL_STORAGE)
                                        .request((permissions, allGranted) -> {
                                            if (allGranted) {
                                                downloadApk();
                                            } else {
                                                ToastUtil.show("权限未全部同意！");
                                            }
                                        });
                            }
                        }, null, false);
            }
            if (!updateDialog.isShow()) {
                updateDialog.show();
            }

        }, throwable -> ToastUtil.show(throwable.getMessage()));
        getDisposables().add(d);
    }

    public void downloadApk() {
        if (lastestApkBean == null) {
            ToastUtil.show("无信息");
            return;
        }

        String fileName = lastestApkBean.getBuildName() + lastestApkBean.getBuildVersion() + ".apk";
        File saveFile = new File(BaseApplication.getInstance().getExternalCacheDir().getAbsolutePath(), fileName);
        String url = lastestApkBean.getDownloadURL();
        HrLogUtil.d("下载apk:" + saveFile.getName() + ", 下载路径:" + url);

        DownloadHelper.download(PgyerApi.HOST_PGYER, url, saveFile.getAbsolutePath(),
                new DownloadListener() {

                    LoadingPopupView dialog = (LoadingPopupView) new XPopup.Builder(MoneyListActivity.this)
                            .dismissOnBackPressed(false)
                            .dismissOnTouchOutside(false)
                            .asLoading("正在下载最新版本")
                            .show();

                    @Override
                    public void onStart() {
                        ScreenAlwaysLightUtil.setOn(MoneyListActivity.this);
                        dialog.show();
                    }

                    @Override
                    public void onProgress(int progress) {
                        dialog.setTitle(String.format("正在下载:%d%%", progress));
                    }

                    @Override
                    public void onFinish(String path) {
                        dialog.setTitle("下载完成...");
                        if (dialog.isShow()) {
                            dialog.dismiss();
                        }
                        File downFile = new File(path);
                        HrLogUtil.i("下载完成 文件位置:" + downFile.getAbsolutePath()
                                + ", 文件大小:" + downFile.length());
                        MoneyListActivity.this.startActivity(IntentUtil.getInstallIntent(MoneyListActivity.this, downFile));
                        ScreenAlwaysLightUtil.setOff(MoneyListActivity.this);
                    }

                    @Override
                    public void onFail(String errorInfo) {
                        if (dialog.isShow()) {
                            dialog.dismiss();
                        }
                        ToastUtil.show("下载失败:" + errorInfo);
                        ScreenAlwaysLightUtil.setOff(MoneyListActivity.this);
                    }
                });
    }

    @Override
    protected void initView(Bundle savedInstanceState) {
        startStamp = DateUtil.getFirstStampOfToday(-30);
        endStamp = DateUtil.getFirstStampOfToday(1) - 1L;
        binding.tvStartTimeFilter.setText(DateUtil.stamp2YmdStr(startStamp));
        binding.tvEndTimeFilter.setText(DateUtil.stamp2YmdStr(endStamp));
        binding.llTimeChoice.setOnClickListener(v1 -> {
            CalendarPicker picker = new CalendarPicker(MoneyListActivity.this);
            picker.setSelectedDate(startStamp, endStamp);
            picker.setOnRangeDatePickListener((startDate, endDate) -> {
                MoneyListActivity.this.startStamp = DateUtil.getFirstStampOfDay(startDate, 0);
                MoneyListActivity.this.endStamp = DateUtil.getFirstStampOfDay(endDate, 1) - 1;
                binding.tvStartTimeFilter.setText(DateUtil.stamp2YmdStr(startStamp));
                binding.tvEndTimeFilter.setText(DateUtil.stamp2YmdStr(endStamp));
                queryTotal();
            });
            picker.show();
        });
        prvm = new PageRecyclerViewManager<MoneyDTO>()
                .setContext(this)
                .setRecyclerView(binding.recyclerview)
                .setAdapter(new BaseQuickAdapter<MoneyDTO, BaseViewHolder>(R.layout.item_money) {
                    @Override
                    protected void convert(@NonNull BaseViewHolder baseViewHolder, MoneyDTO item) {
                        baseViewHolder.setText(R.id.item_1, item.getPerson());
                        baseViewHolder.setText(R.id.item_2, String.format("%s ¥%s",
                                item.getMoneyInFlag() == 1 ? "收入" : "支出",
                                StringUtil.getObjStr(item.getMoney(), "0")));
                        baseViewHolder.setTextColor(R.id.item_2, item.getMoneyInFlag() == 1 ?
                                getColor(R.color.material_red) : getColor(R.color.material_green));
                        baseViewHolder.setText(R.id.item_3, item.getNote());
                        baseViewHolder.setText(R.id.item_4, DateUtil.stamp2YmdStr(item.getTradeTime()));
                    }
                })
                .setDivider(true)
                .setSize(20)
                .setOnItemClickListener((baseQuickAdapter, view, i) -> {
                    new XPopup.Builder(MoneyListActivity.this)
                            .atView(view)
                            .hasShadowBg(false)
                            .animationDuration(0)
                            .asAttachList(new String[]{"编辑", "删除"},
                                    new int[]{R.drawable.icon_note, R.drawable.icon_delete},
                                    (position, text) -> {
//                                        ToastUtil.show("click " + text);
                                        if ("编辑".equals(text)) {
                                            showItemDialog(prvm.getRvList().get(i));
                                        } else if ("删除".equals(text)) {
                                            MoneyDTO item = prvm.getRvList().get(i);
                                            item.setUpdateTime(System.currentTimeMillis());
                                            item.setDeleteflag((byte) 1);
                                            insertOrUpdateMoney(item);
                                        }
                                    })
                            .show();
                })
                .setRefreshListener(new OnRefreshLoadMoreListener() {
                    @Override
                    public void onLoadMore(@NonNull RefreshLayout refreshLayout) {
                        queryList(PageRecyclerViewManager.LOADMORE);
                    }

                    @Override
                    public void onRefresh(@NonNull RefreshLayout refreshLayout) {
                        queryList(PageRecyclerViewManager.FRESH);
                    }
                })
                .setRefreshLayout(binding.refreshLayout)
                .setRefresh(true)
                .setLoadMore(true)
                .build();
    }

    private void queryTotal() {
        HashMap<String, String> header = new HashMap<>();
        header.put("Authorization", "Bearer " + SupabaseManager.APP_KEY);
        header.put("apikey", SupabaseManager.APP_KEY);
        HashMap<String, String> param = new HashMap<>();
        param.put("select", "moneyInFlag, money");
        param.put("tradeTime", "gte." + startStamp);
        param.put("deleteflag", "neq.1");
        @io.reactivex.rxjava3.annotations.NonNull
        Disposable d = SupabaseManager.getInstance().getService().selectMoney3(header, param, "lt." + endStamp)
                .compose(AsyncUtils.getThreadTransformer())
                .subscribe(data -> {
                    if (EmptyUtil.isEmpty(data)) {
                        return;
                    }
                    BigDecimal inTotal = BigDecimal.ZERO;
                    BigDecimal outTotal = BigDecimal.ZERO;
                    for (MoneyDTO item : data) {
                        if (item.getMoney() != null && item.getMoneyInFlag() != null) {
                            if (item.getMoneyInFlag() == 1) {
                                inTotal = inTotal.add(BigDecimal.valueOf(item.getMoney()));
                            } else {
                                outTotal = outTotal.add(BigDecimal.valueOf(item.getMoney()));
                            }
                        }
                    }
                    binding.tvTotalIn.setText("收入：¥" + StringUtil.getObjStr(inTotal, "0"));
                    binding.tvTotalOut.setText("支出：¥" + StringUtil.getObjStr(outTotal, "0"));
                }, throwable -> {
                    ToastUtil.show("查询失败：" + throwable.getMessage());
                });
        getDisposables().add(d);
    }

    private void insertOrUpdateMoney(MoneyDTO item) {
        HashMap<String, String> header = new HashMap<>();
        header.put("Authorization", "Bearer " + SupabaseManager.APP_KEY);
        header.put("apikey", SupabaseManager.APP_KEY);
        header.put("Content-Type", "application/json");
        header.put("Prefer", "resolution=merge-duplicates");
//        HashMap<String, String> param = new HashMap<>();
//        param.put("deleteflag", "1");
//        param.put("uuid", item.getUuid());
//        param.put("updateTime", System.currentTimeMillis() + "");
        RequestBody requestBody = RequestBody.create(MediaType.parse("application/json"), GsonUtil.obj2JsonStr(item));
        @io.reactivex.rxjava3.annotations.NonNull
        Disposable d = SupabaseManager.getInstance().getService().insertOrUpdateMoney(requestBody, header)
                .compose(AsyncUtils.getThreadTransformer())
                .subscribe(dbDate2 -> {
                    queryList(PageRecyclerViewManager.FRESH);
                    queryTotal();
                }, throwable -> {
                    if (NetUtil.isSupabaseSuccessThrowable(throwable)) {
                        queryList(PageRecyclerViewManager.FRESH);
                        queryTotal();
                        return;
                    }
                    ToastUtil.show("查询失败：" + throwable.getMessage());
                });
        getDisposables().add(d);
    }

//    @Override
//    protected void initData() {
//        queryList(PageRecyclerViewManager.FRESH);
//    }

    @Override
    protected void initListener() {
        binding.imgEdit.setOnClickListener(v -> {
            MoneyDTO item = new MoneyDTO();
            item.setMoneyInFlag(0);
            item.setMoney(0d);
            showItemDialog(item);
        });
        binding.etSearch.setOnKeyListener((v, keyCode, event) -> {
            if (KeyEventUtil.isEnter(keyCode)) {
                queryList(PageRecyclerViewManager.FRESH);
                return true;
            }
            return false;
        });
    }

    private void showItemDialog(MoneyDTO item) {
        new XPopup.Builder(MoneyListActivity.this)
                .asCustom(new MoneyEditDialog(MoneyListActivity.this, item, item2 -> {
                    insertOrUpdateMoney(item2);
                }))
                .show();
    }

    private void queryList(String refreshType) {
        prvm.setDataChangeType(refreshType);
        HashMap<String, String> header = new HashMap<>();
        header.put("Authorization", "Bearer " + SupabaseManager.APP_KEY);
        header.put("apikey", SupabaseManager.APP_KEY);
        // 精确返回符合条件的记录总数 Prefer: count=exact
        // 响应中会包含 Content-Range: items 0-9/100
        header.put("Prefer", "count=exact");
        header.put("Range", String.format("%d-%d", (prvm.getPage() - 1) * prvm.getSize(), prvm.getPage() * prvm.getSize() - 1));
        HashMap<String, String> param = new HashMap<>();
        param.put("select", "*");
        param.put("deleteflag", "neq.1");
        param.put("order", "tradeTime.desc");
        if (EmptyUtil.isNotEmpty(binding.etSearch.getText())) {
            param.put("person", "like.%" + binding.etSearch.getText() + "%");
        }
        @io.reactivex.rxjava3.annotations.NonNull
        Disposable d = SupabaseManager.getInstance().getService().selectMoney2(header, param)
                .compose(AsyncUtils.getThreadTransformer())
                .subscribe(response -> {
                    if (!response.isSuccessful()) {
                        ToastUtil.show("查询失败");
                        prvm.freshPageData(new ArrayList<>(), 0);
                        return;
                    }
                    if (EmptyUtil.isEmpty(response.body())) {
                        ToastUtil.show("查询数据为空");
                        prvm.freshPageData(new ArrayList<>(), 0);
                        return;
                    }
                    long countInt = 0;
                    try {
                        String count = response.headers().get("Content-Range").split("/")[1];
                        countInt = Long.parseLong(count);
                    } catch (Exception e) {
                        HrLogUtil.e("err:", e);
                    }
                    List<MoneyDTO> data = GsonUtil.copyList(response.body(), MoneyDTO.class);
                    prvm.freshPageData(data, countInt);

                }, throwable -> ToastUtil.show("查询失败：" + throwable.getMessage()));
        getDisposables().add(d);
    }

}